package ptij.ADSL.pn;

import ptolemy.kernel.*;
import ptolemy.kernel.util.*;
import ptolemy.data.*;
import ptolemy.data.expr.*;
import ptolemy.actor.*;
import ptolemy.domains.pn.kernel.*;

import java.io.*;
import java.util.Vector;

public class CustomerNetTx extends TypedAtomicActor {
            
    /* Output Ports */
    public TypedIOPort LS0;
    public TypedIOPort dataTx;
    
    /* Parameters */    
    public Parameter LS0_Rate;

    public CustomerNetTx(TypedCompositeActor container, String name) throws
        NameDuplicationException, IllegalActionException {
        super(container, name);
    
	LS0 = new TypedIOPort(this, "LS0", false, true);
	LS0.setTypeEquals(ObjectToken.class);
	
	dataTx = new TypedIOPort(this, "dataTx", false, true);
	dataTx.setTypeEquals(IntToken.class);

	LS0_Rate = new Parameter(this, "LS0_Rate", new IntToken(1));	
    }

    public void fire() throws IllegalActionException {

	if(_nextFireLS0 == 0) {
	    ObjectToken ot = new ObjectToken(new Integer(_data[_counter]));
            LS0.broadcast(ot);
	    dataTx.broadcast(new IntToken(0));

  	    _counter = (_counter + 1) % _data.length;
  	    _nextFireLS0 = 1000.0 / _LS0_Rate;
 	}
	_nextFire();

    }

    public void initialize() throws IllegalActionException {
        super.initialize();
	IntToken t = (IntToken) LS0_Rate.getToken();
	_LS0_Rate = t.intValue();
	_nextFireLS0 = 1000.0 / _LS0_Rate;
	
	try {
            File f = new File("test.dat");
            FileInputStream fi = new FileInputStream(f);
            DataInputStream data = new DataInputStream(fi);
            
	    _data = new int[((int) f.length())/4];
	    for(int i = 0;i < _data.length;i++) {
	        _data[i] = data.readInt();
	    }
	    data.close();
	    fi.close(); 
	} 
	catch(IOException ex) {
	    System.out.println(ex);
        }
	_counter = 0;
    }

    private void _nextFire() throws IllegalActionException {
        double min = 1000.0;
	boolean sched = false;
	
	Director d = getDirector();
	
	if(_nextFireLS0 < min) min = _nextFireLS0;
	
	if(_nextFireLS0 - min == 0) {
	    d.fireAt(this, d.getCurrentTime() + _nextFireLS0);
	    sched = true;
	}
	_nextFireLS0 -= min;
	
    }       

    private int _LS0_Rate;
    private double _nextFireLS0;
    private double _nextFire;
     
    private int [] _data;
    private int _counter;
}
